package com.shiku.imserver;

import com.shiku.imserver.common.ImSessionContext;
import com.shiku.imserver.common.tcp.TcpSessionContext;
import com.shiku.imserver.common.ws.WsSessionContext;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ReadCompletionHandler;
import org.tio.core.Tio;
import org.tio.core.ssl.SslFacadeContext;
import org.tio.core.ssl.SslUtils;
import org.tio.server.AcceptCompletionHandler;
import org.tio.server.ServerGroupStat;
import org.tio.server.TioServer;
import org.tio.utils.SystemTimer;

public class ShikuAcceptCompletionHandler extends AcceptCompletionHandler {
    private static Logger log = LoggerFactory.getLogger(AcceptCompletionHandler.class);
    private byte protocol;
    private AsynchronousServerSocketChannel serverSocketChannel;

    public ShikuAcceptCompletionHandler(AsynchronousServerSocketChannel serverSocketChannel2, byte protocol2) {
        this.protocol = protocol2;
        this.serverSocketChannel = serverSocketChannel2;
    }

    /* JADX DEBUG: Failed to find minimal casts for resolve overloaded methods, cast all args instead
     method: MutableMD:<T>:(java.net.SocketOption, java.lang.Object):java.nio.channels.AsynchronousSocketChannel throws java.io.IOException
     arg types: [java.net.SocketOption, boolean]
     candidates:
      ClspMth{java.nio.channels.AsynchronousSocketChannel.setOption(java.net.SocketOption, java.lang.Object):java.nio.channels.NetworkChannel throws java.io.IOException}
      MutableMD:<T>:(java.net.SocketOption, java.lang.Object):java.nio.channels.NetworkChannel throws java.io.IOException
      MutableMD:<T>:(java.net.SocketOption, java.lang.Object):java.nio.channels.AsynchronousSocketChannel throws java.io.IOException */
    /* JADX DEBUG: Failed to find minimal casts for resolve overloaded methods, cast all args instead
     method: MutableMD:<T>:(java.net.SocketOption, java.lang.Object):java.nio.channels.AsynchronousSocketChannel throws java.io.IOException
     arg types: [java.net.SocketOption, int]
     candidates:
      ClspMth{java.nio.channels.AsynchronousSocketChannel.setOption(java.net.SocketOption, java.lang.Object):java.nio.channels.NetworkChannel throws java.io.IOException}
      MutableMD:<T>:(java.net.SocketOption, java.lang.Object):java.nio.channels.NetworkChannel throws java.io.IOException
      MutableMD:<T>:(java.net.SocketOption, java.lang.Object):java.nio.channels.AsynchronousSocketChannel throws java.io.IOException */
    public void completed(AsynchronousSocketChannel asynchronousSocketChannel, TioServer tServer) {
        ShikuTioServer tioServer = null;
        try {
            tioServer = (ShikuTioServer) tServer;
            ImServerGroupContext serverGroupContext = (ImServerGroupContext) tioServer.getServerGroupContext();
            ImSessionContext sessionContext = null;
            if (1 == this.protocol) {
                sessionContext = new TcpSessionContext();
                sessionContext.setProtocolHandler(serverGroupContext.getTcpServerAioHandler());
            } else if (2 == this.protocol) {
                sessionContext = new WsSessionContext();
                sessionContext.setProtocolHandler(serverGroupContext.getWsServerAioHandler());
            }
            
            ((InetSocketAddress) asynchronousSocketChannel.getRemoteAddress()).getHostString();
            if (serverGroupContext.statOn) {
               // serverGroupContext.groupStat.accepted.incrementAndGet();
                ((ServerGroupStat)serverGroupContext.groupStat).accepted.incrementAndGet();
            }
            asynchronousSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
            asynchronousSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF,  65536);
            asynchronousSocketChannel.setOption(StandardSocketOptions.SO_SNDBUF,  65536);
            asynchronousSocketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE,  true);
            ImServerChannelContext channelContext = new ImServerChannelContext(serverGroupContext, asynchronousSocketChannel);
            channelContext.groupContext = serverGroupContext;
            if (2 != this.protocol) {
                channelContext.init(serverGroupContext, asynchronousSocketChannel);
            } else if (serverGroupContext.sslConfig != null) {
                try {
                    SslFacadeContext sslFacadeContext = new SslFacadeContext(channelContext);
                    channelContext.init(serverGroupContext, asynchronousSocketChannel);
                    if (serverGroupContext.isServer()) {
                        sslFacadeContext.beginHandshake();
                    }
                } catch (Exception e) {
                    log.error("在开始SSL握手时发生了异常", e);
                    Tio.close(channelContext, "在开始SSL握手时发生了异常" + e.getMessage());
                    if (tioServer.isWaitingStop()) {
                        log.info("{}即将关闭服务器，不再接受新请求", tioServer.getServerNode());
                        return;
                    } else {
                        this.serverSocketChannel.accept(tioServer, this);
                        return;
                    }
                }
            } else {
                channelContext.init(serverGroupContext, asynchronousSocketChannel);
            }
            channelContext.setClosed(false);
            channelContext.stat.setTimeFirstConnected(Long.valueOf(SystemTimer.currTime));
            channelContext.setServerNode(tioServer.getServerNode());
            serverGroupContext.ips.bind(channelContext);
            channelContext.setAttribute(sessionContext);
            if (serverGroupContext.getServerAioListener() != null && !SslUtils.isSsl(channelContext.groupContext)) {
                try {
                    serverGroupContext.getServerAioListener().onAfterConnected(channelContext, true, false);
                } catch (Throwable e2) {
                    log.error(e2.toString(), e2);
                }
            }
            if (!tioServer.isWaitingStop()) {
                ReadCompletionHandler readCompletionHandler = channelContext.getReadCompletionHandler();
                ByteBuffer readByteBuffer = readCompletionHandler.getReadByteBuffer();
                readByteBuffer.position(0);
                readByteBuffer.limit(readByteBuffer.capacity());
                asynchronousSocketChannel.read(readByteBuffer, readByteBuffer, readCompletionHandler);
            }
            if (tioServer.isWaitingStop()) {
                log.info("{}即将关闭服务器，不再接受新请求", tioServer.getServerNode());
            } else {
                this.serverSocketChannel.accept(tioServer, this);
            }
        } catch (Throwable th) {
            if (tioServer.isWaitingStop()) {
                log.info("{}即将关闭服务器，不再接受新请求", tioServer.getServerNode());
            } else {
                this.serverSocketChannel.accept(tioServer, this);
            }
           // throw th;
        }
    }

    public void failed(Throwable exc, TioServer tioServer) {
        this.serverSocketChannel.accept(tioServer, this);
        log.error("[" + tioServer.getServerNode() + "]监听出现异常", exc);
    }
}
